#include "cppTutorExceptionHandling.h"

#include <string>
#include <iostream>

using namespace std;

CExceptionHandling :: CExceptionHandling ()
{
    cout << "ENTER : CExceptionHandling :: CExceptionHandling ()" << endl;
    cout << "EXIT  : CExceptionHandling :: CExceptionHandling ()" << endl;
}

CExceptionHandling :: CExceptionHandling (int nValue = 0) : m_nValue (nValue)
{
    cout << "ENTER : CExceptionHandling :: CExceptionHandling (int)" << endl;
    cout << "EXIT  : CExceptionHandling :: CExceptionHandling (int)" << endl;
}

CExceptionHandling :: ~CExceptionHandling ()
{
    cout << "ENTER : CExceptionHandling :: ~CExceptionHandling ()" << endl;
    cout << "EXIT  : CExceptionHandling :: ~CExceptionHandling ()" << endl;
}

void CExceptionHandling :: m_DisplayValue ()
{
    cout << "ENTER : CExceptionHandling :: m_DisplayValue ()" << endl;
    cout << m_nValue << endl;
    cout << "EXIT  : CExceptionHandling :: m_DisplayValue ()" << endl;
}
void CExceptionHandling :: m_StackUnwinding ()
{
    cout << "ENTER : CExceptionHandling :: m_StackUnwinding ()" << endl;
    // if the try block doesn't have a catch handler for the type of the exception being thrown,
    // stack unwinding occurs just as if there were no try blocl at all
    try 
    {
        m_StackUnwindingFirst ();
    }
    catch (string)
    {
        cerr << "Negative Number Found !!!" << endl;
    }
    cout << "EXIT  : CExceptionHandling :: m_StackUnwinding ()" << endl;
}

void CExceptionHandling :: m_StackUnwindingFirst ()
{
    cout << "ENTER : CExceptionHandling :: m_StackUnwindingFirst ()" << endl;
    
    // immediate caller of the functiomn that throws the exception doesn't have to handle
    // the exception if he doesn't want to.
    m_StackUnwindingSecond ();

    cout << "EXIT  : CExceptionHandling :: m_StackUnwindingFirst ()" << endl;
}

void CExceptionHandling :: m_StackUnwindingSecond ()
{
    cout << "ENTER : CExceptionHandling :: m_StackUnwindingSecond ()" << endl;
    if (m_nValue == -1)
    {
        cerr << "Negative Number Found !!!" << endl;
        throw -1;
    }
    cout << "EXIT  : CExceptionHandling :: m_StackUnwindingSecond ()" << endl;
}
